package vip.xiaonuo.bi.core.datasource.util;

import vip.xiaonuo.bi.core.dataset.enums.DataSetRowType;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @auther: 顾育司
 * @Description 数据列类型数据等相关工具类
 * @date: 2024/1/9
 */
public class ColumnUtils {
    /**
     * 判断出每一列的类型
     * @param dataList
     * @return
     */
    public static Map<String,String> getColumnType(List<Map<String, String>> dataList){
        // 定义结果集 即列类型
        Map<String,String> map =  new HashMap<>();
        // 判断数量
       int flag = 100;
        // 遍历数据判断
        dataList.subList(0,dataList.size()>flag?flag:dataList.size()).stream().parallel().forEach(item->{
            item.forEach((k,v)->{
                // 判断数量
                String dataType = map.getOrDefault(k,"");
                if (dataType.equals("STRING")) {
                    // 如果是String类型 就是全部兼容 不需要再判断
                }else {
                    // 对数值判断出类型 如果和上一次结果不一样则是String类型
                    String predictType = DateTypePredictUtils.getListDataType(v);
                     if(!"".equals(dataType)&& !dataType.equals(predictType)){
                         map.put(k,"STRING");
                     }else{
                        // 相同则添加
                        map.put(k,predictType);
                    }

                }
            });
        });

        return map;
    }

    /**
     * 判断出每一列的类型
     * @param dataList
     * @return
     */
    public static Map<String,String> getColumnType(List<List<String>> dataList,List<String> colNames){
        // 定义结果集 即列类型
        Map<String,String> map =  new LinkedHashMap<>();
        // 收集数量 如果这个字段的null个数和dataList 条数一样 那说明这一列都是null 则给他默认值STRING
        Map<String,Integer> countMap =  new LinkedHashMap<>();
        // 判断数量
        int flag = 100;
        // 遍历数据判断
        dataList.subList(0,dataList.size()>flag?flag:dataList.size()).stream().forEach(item->{
            for (int i = 0; i < item.size(); i++) {
                // 该值
                String value = item.get(i);
                // 列名
                String colName = colNames.get(i);
                // 获取列的类型
                String dataType = map.getOrDefault(colName,"");
                if (dataType.equals("STRING")) {
                    continue;
                    // 如果是String类型 就是全部兼容 不需要再判断
                }else {
                    if (value == null ){
                        countMap.putIfAbsent(colName,0);
                        countMap.computeIfPresent(colName,(p,v)->v+1);
                       // 为空个数和条数一样 那说明这一列都是null 则给他默认值STRING
                        if(countMap.get(colName)==dataList.size()){
                            map.put(colName,"STRING");
                        }
                        continue;
                    }
                    // 对数值判断出类型
                    String predictType = DateTypePredictUtils.getListDataType(value);
                    // 如果和上一次结果不一样则是String类型
                    if(!"".equals(dataType)&& !dataType.equals(predictType)){
                        map.put(colName,"STRING");
                    }else{
                        // 相同则添加
                        map.put(colName,predictType);
                    }
                }
            }
        });

        return map;
    }



    /**
     *  列转化 对对应的列改变类型值
     * @param dataList
     * @return
     */
    public static List<Map<String, String>> convertColumnDataByTypeMapData(List<Map<String, String>> dataList,Map<String,String> columnType){
        dataList.stream().parallel().forEach(item->{
            columnType.forEach((k,v)->{
                // 对对应的列改变类型值
                item.put(k, DataSetRowType.getType(k).converData(item.get(k)));
            });
        });
        return dataList;
    }

    /**
     *  列转化 对对应的列改变类型值
     * @param dataList
     * @return
     */
    public static List<List<String>> convertColumnDataByTypeListData(List<List<String>> dataList,List<String> cols,Map<String,String> columnType){
        // 获取指定的索引位置
        Map<String,Integer> positionMap = new HashMap<>();
        columnType.forEach((k,v)->{
            // 列名称-->list中位置
            positionMap.put(k,cols.indexOf(k));
                });
        // 遍历数据 ==》替换指定列的位置值
        dataList.stream().parallel().forEach(item->{
            columnType.forEach((k,v)->{// (列名，类型)

                /* 对对应的列改变类型值  */
                // 当前位置
                int position = positionMap.get(k);
                // 当前值
                String currVal = item.get(position);
                // 目标值
                String targetVal = DataSetRowType.getType(v).converData(currVal);
                // 替换
                item.set(position,targetVal);
            });
        });
        return dataList;
    }
}
